package com.fingard.dsp.bank.directbank.ceb01;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.directbank.citic02.CITIC02RealTime;
import com.fingard.dsp.bank.reqrespobj.balancecheck.RetAtsBalCheckQry;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingle;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingle;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import org.springframework.stereotype.Component;

import java.io.File;
import java.sql.Connection;
import java.util.*;

/**
 * @author: Parker
 * @create: 2020-01-02 09:46
 * @version: 1.0
 **/
@Component("CEB01BatPayRec")
public class CEB01BatPayRec extends CEB01Base implements IBatPayRec {
    String fileSp = "\\|";//批量支付文件列分隔符
    String fileEndSp = "\r\n";//批量支付文件行分隔符

    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        try {
            if("198801CNVRT".equals(p_req1988.reqHeader.commandCode)){
                if(p_req1988.getTotalNum() == 1){
                    ReqSingle req1908 = new ReqSingle(p_req1988);//批量转单笔
                    CEB01SinglePay tmpSinglePay = new CEB01SinglePay();
                    tmpSinglePay.setSbLog(this.sbLog);
                    tmpSinglePay.setLogFlushTime(this.logFlushTime);
                    tmpSinglePay.reqHeader = req1908.reqHeader;
                    tmpSinglePay.bankFront = this.bankFront;
                    req1908.singleDetail.askNumber = p_req1988.reqBatchNO;//批次号作为单笔流水号
                    RetAtsSingle retAts1908 = tmpSinglePay.d_1908_SglPay(req1908);
                    retAts1908.fillToBatRetAts(retAts);
                }else{
                    retAts.fillBatchFailed(p_req1988, FailCode.E9981, "总笔数需为1");
                }
            }else{
                retAts.writeStart();
                Connection conn = FGBiz.getLocalDbConn();
                //第一步：查询代发协议号
                CEB01Header bankHeader = new CEB01Header();
                bankHeader.TransCode = "b2e005004";
                bankHeader.batchID = getBatchID();
                bankHeader.JnlDateTime = new Date();

                XmlTextWriter xmlWriter = new XmlTextWriter();
                String[] bankResult = null;

                String protocolNum = getBankConfig().getValueAsString("protocolNum");

                if (StringHelper.hasAnyChar(protocolNum)) {
                    writeCommonHeader_2(xmlWriter, bankHeader);
                    xmlWriter.writeStartElement("TransContent");
                    xmlWriter.writeStartElement("ReqData");
                    xmlWriter.writeElementString("ClientPatchID", getBatchID());//客户端批内序号/客户交易号
                    xmlWriter.writeElementString("AcNo", p_req1988.ownAct);//代发账号
                    xmlWriter.writeEndDocument();

                    WriteBankLogLn("查询代发协议号：");
                    bankResult = sendToBank_2(xmlWriter.toXmlString(), bankHeader.TransCode);//发送银行
                    if (bankResult[0].length() == 0) {
                        StringBuilder tmpSbMsg = new StringBuilder();
                        //解析银行返回
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                        if (tmpBkReader != null) {
                            String tmpReturnCode = tmpBkReader.getFirstText("/Transaction/TransContent/ReturnCode");
                            String tmpReturnMsg = tmpBkReader.getFirstText("/Transaction/TransContent/ReturnMsg");
                            if (tmpReturnCode != null && "0000".equals(tmpReturnCode)) {
                                while (tmpBkReader.read("/Transaction/TransContent/BatchRespList/RespData")) {
                                    if ("198801".equals(p_req1988.reqHeader.commandCode)) {//代发工资
                                        if ("1".equals(tmpBkReader.readedXElement.getSingleText("YEWUZL"))) {
                                            protocolNum = tmpBkReader.readedXElement.getSingleText("XYSHBH");
                                        }
                                    } else {//代发其他
                                        protocolNum = tmpBkReader.readedXElement.getSingleText("XYSHBH");
                                    }
                                    if (StringHelper.hasAnyChar(protocolNum)) {
                                        break;
                                    }
                                }
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = tmpReturnMsg;
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = tmpSbMsg.toString();
                        }
                    } else if (bankResult[0].equals(ConnState.FAIL)) {
                        retAts.respCode = "0";
                        retAts.respInfo = bankResult[1];
                        retAts.reqSeqID = p_req1988.reqBatchNO;
                        retAts.transState = PaymentState.FAIL_Batch;
                        retAts.payInfoCode = bankResult[0];
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = bankResult[1];
                    }
                }

                String bankFileName = null;
                if (StringHelper.hasAnyChar(protocolNum)) {
                    WriteBankLogLn("生成并上传批量支付文件：");
                    String fileName = p_req1988.reqBatchNO + ".txt";
                    String filePath = StringHelper.trimEndFileSp(getBankConfig().getValueAsString("batchPayFileUpPath")) + File.separator + fileName;
                    String payFileContent = getPayFileContent(p_req1988);
                    FileHelper.writeFile(filePath, payFileContent, getCharset());
                    if (FileHelper.existFile(filePath)) {
                        bankResult = sendToBankUploadFile("b2e005005", fileName, getBatchID());
                        if (bankResult[0].length() == 0) {
                            StringBuilder tmpSbMsg = new StringBuilder();
                            //解析银行返回
                            XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                            if (tmpBkReader != null) {
                                String tmpReturnCode = tmpBkReader.getFirstText("/Transaction/TransContent/ReturnCode");
                                String tmpReturnMsg = tmpBkReader.getFirstText("/Transaction/TransContent/ReturnMsg");
                                if (tmpReturnCode != null && "0000".equals(tmpReturnCode)) {
                                    bankFileName = tmpBkReader.getFirstText("/Transaction/TransContent/RespData/EbankFName");
                                } else {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = tmpReturnMsg;
                                }
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = tmpSbMsg.toString();
                            }
                        } else if (bankResult[0].equals(ConnState.FAIL)) {
                            retAts.respCode = "0";
                            retAts.respInfo = bankResult[1];
                            retAts.reqSeqID = p_req1988.reqBatchNO;
                            retAts.transState = PaymentState.FAIL_Batch;
                            retAts.payInfoCode = bankResult[0];
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = bankResult[1];
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = "生成支付文件失败";
                    }
                }

                if (StringHelper.hasAnyChar(bankFileName)) {
                    WriteBankLogLn("批量支付确认：");
                    bankHeader.TransCode = "b2e005005";
                    bankHeader.batchID = getBatchID();
                    bankHeader.JnlDateTime = new Date();
                    xmlWriter = new XmlTextWriter();
                    writeCommonHeader_2(xmlWriter, bankHeader);
                    xmlWriter.writeStartElement("TransContent");
                    xmlWriter.writeStartElement("ReqData");
                    xmlWriter.writeElementString("ClientPatchID", p_req1988.reqBatchNO);//客户端批内序号/客户交易号
                    xmlWriter.writeElementString("AcNo", p_req1988.ownAct);//代发账号
                    xmlWriter.writeElementString("Amount", p_req1988.totalAmt);//总金额
                    xmlWriter.writeElementString("TotalPathes", p_req1988.totalNum);//总笔数
                    xmlWriter.writeElementString("DealMode", "1");//处理方式 1-日间处理 0-日终处理
                    xmlWriter.writeElementString("FileName", bankFileName);//文件名
                    xmlWriter.writeElementString("DealDate", Format.Date8Format.format(Format.Date10Format.parse(p_req1988.payDate)));//处理日期
                    xmlWriter.writeElementString("IsCheckUser", getBankConfig().getValueAsString("checkUserInfo"));//是否验证用户资料
                    xmlWriter.writeElementString("ProtocolNum", protocolNum);//协议编号
                    if ("198801".equals(p_req1988.reqHeader.commandCode)) {
                        xmlWriter.writeElementString("Flag", "0");//代发标志 0-代发工资 1-其它代发
                    } else {
                        xmlWriter.writeElementString("Flag", "1");
                    }
                    xmlWriter.writeElementString("Note", "");
                    xmlWriter.writeEndDocument();

                    bankResult = sendToBank_2(xmlWriter.toXmlString(), bankHeader.TransCode);
                    if (bankResult[0].length() == 0) {
                        StringBuilder tmpSbMsg = new StringBuilder();
                        //解析银行返回
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                        if (tmpBkReader != null) {
                            String tmpReturnCode = tmpBkReader.getFirstText("/Transaction/TransContent/ReturnCode");
                            String tmpReturnMsg = tmpBkReader.getFirstText("/Transaction/TransContent/ReturnMsg");
                            retAts.respCode = "0";
                            retAts.respInfo = tmpReturnMsg;
                            retAts.reqSeqID = p_req1988.reqBatchNO;
                            retAts.transState = tmpReturnCode;
                            retAts.payInfoCode = retAts.transState;

                            //记录批次号对应的银行支付批次号，供查询状态接口使用
                            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                            JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_req1988.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1988.reqBatchNO, tmpBkReader.getFirstText("/Transaction/TransContent/RespData/BatchNo")});
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = tmpSbMsg.toString();
                        }
                    } else if (bankResult[0].equals(ConnState.FAIL)) {
                        retAts.respCode = "0";
                        retAts.respInfo = bankResult[1];
                        retAts.reqSeqID = p_req1988.reqBatchNO;
                        retAts.transState = PaymentState.FAIL_Batch;
                        retAts.payInfoCode = bankResult[0];
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = bankResult[1];
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
        }
        retAts.writeRetToATS();
        return retAts;
    }


    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        Connection conn = FGBiz.getLocalDbConn();
        try {
            if("198801CNVRT".equals(p_req1998.reqHeader.commandCode)){
                ReqQrySingle req1944 = new ReqQrySingle(p_req1998);//批量转单笔
                CEB01SinglePay tmpSinglePay = new CEB01SinglePay();
                tmpSinglePay.setSbLog(this.sbLog);
                tmpSinglePay.setLogFlushTime(this.logFlushTime);
                tmpSinglePay.reqHeader = req1944.reqHeader;
                tmpSinglePay.bankFront = this.bankFront;
                RetAtsSingle retAts1944 = tmpSinglePay.d_1944_QrySglPay(req1944);
                retAts1944.fillToBatRetAts(retAts);
            }else{
                //第一步：查询代发结果文件
                CEB01Header bankHeader = new CEB01Header();
                bankHeader.TransCode = "b2e005007";
                bankHeader.batchID = getBatchID();
                bankHeader.JnlDateTime = new Date();

                XmlTextWriter xmlWriter = new XmlTextWriter();
                writeCommonHeader_2(xmlWriter, bankHeader);
                xmlWriter.writeStartElement("TransContent");
                xmlWriter.writeStartElement("ReqData");
                xmlWriter.writeElementString("ClientPatchID", p_req1998.reqBatchNO);//客户端批内序号/客户交易号
                Map<String, Object> selMap = JDBCHelper.execQuerySingle(conn, SELECTSEQ, new Object[]{p_req1998.reqBatchNO, p_req1998.reqHeader.bankCode});
                if (selMap.size() > 0) {
                    xmlWriter.writeElementString("BatchNo", selMap.get("BANKREQSEQID").toString());//处理批次号
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "交易流水号关联映射异常，请检查";
                    retAts.writeBeforeDetail();
                    retAts.writeAfterDetail();
                    return retAts;
                }
                xmlWriter.writeEndDocument();

                String[] bankResult = sendToBank_2(xmlWriter.toXmlString(), bankHeader.TransCode);

                List<String> fileList = new ArrayList<String>();
                if (bankResult[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    //解析银行返回
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String tmpReturnCode = tmpBkReader.getFirstText("/Transaction/TransContent/ReturnCode");
                        String tmpReturnMsg = tmpBkReader.getFirstText("/Transaction/TransContent/ReturnMsg");
                        if (tmpReturnCode != null && "0000".equals(tmpReturnCode)) {
                            fileList.add(tmpBkReader.getFirstText("/Transaction/TransContent/RespData/SucesFileName"));
                            fileList.add(tmpBkReader.getFirstText("/Transaction/TransContent/RespData/FailFileName"));
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpSbMsg.toString();
                    }
                } else if (bankResult[0].equals(ConnState.FAIL)) {
                    retAts.respCode = "0";
                    retAts.respInfo = bankResult[1];
                    retAts.reqSeqID = p_req1998.reqBatchNO;
                    retAts.transState = PaymentState.FAIL_Batch;
                    retAts.payInfoCode = bankResult[0];
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = bankResult[1];
                }

                Iterator<String> iterator = fileList.iterator();
                //下载文件存放前置机目录
                String batchPayFileDownPath = this.getBankConfig().getValueAsString("batchPayFileDownPath");
                while (iterator.hasNext()) {
                    String fileName = StringHelper.getFileName(iterator.next());
                    if (StringHelper.hasAnyChar(fileName)) {
                        //下载支付成功文件
                        String[] tmpStrRetDownLoad = sendToBankDownloadFile("", bankHeader.TransCode, fileName);
                        XmlTextReader tmpBkReaderDownLoad;
                        if (tmpStrRetDownLoad[0].length() == 0) {
                            StringBuilder tmpSbMsgDownLoad = new StringBuilder();
                            tmpBkReaderDownLoad = loadBankRespXmlReader(tmpStrRetDownLoad[1], tmpSbMsgDownLoad);
                            if (tmpBkReaderDownLoad != null) {
                                String success = tmpBkReaderDownLoad.getFirstText("/transaction/success");
                                String error = tmpBkReaderDownLoad.getFirstText("/transaction/error");
                                if (!StringHelper.isNullOrEmpty(success) && StringHelper.isNullOrEmpty(error)) {
                                    //处理支付结果文件
                                    if (FileHelper.existFile(batchPayFileDownPath + File.separator + fileName)) {
                                        WriteBankLogLn("批量支付结果文件：" + fileName + "下载成功!");

                                        String sucesFileContent = FileHelper.readFileText(batchPayFileDownPath + File.separator + fileName, getCharset());
                                        String[] fileLine = sucesFileContent.split(fileEndSp);
                                        for (int i = 0; i < fileLine.length; i++) {
                                            if (fileLine[i].contains(fileSp)) {
                                                RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                                String selectSQL = "SELECT REQSEQID FROM REQSEQIDMAPPING WHERE REQBATCHNO=? AND BANKCODE=? AND BANKREQSEQID=?;";
                                                String[] columns = fileLine[i].split(fileSp);
                                                tmpRetDetail.payAct = p_req1998.ownAct;
                                                tmpRetDetail.recAct = columns[1];//收款人账号
                                                tmpRetDetail.recName = columns[3];//收款人名称
                                                selMap = JDBCHelper.execQuerySingle(conn, selectSQL, new Object[]{p_req1998.reqBatchNO, p_req1998.reqHeader.bankCode, columns[0]});
                                                if (selMap.size() > 0) {
                                                    tmpRetDetail.postScript = selMap.get("REQSEQID").toString();//批内流水号
                                                } else {
                                                    retAts.respCode = "-1";
                                                    retAts.respInfo = "支付结果批内流水号关联映射异常，请检查";
                                                    retAts.writeBeforeDetail();
                                                    retAts.writeAfterDetail();
                                                    return retAts;
                                                }
                                                tmpRetDetail.payAmount = columns[2];//金额
                                                tmpRetDetail.memo = "";//备注
                                                tmpRetDetail.result = columns[4];
                                                tmpRetDetail.payInfoCode = tmpRetDetail.result;
                                                retAts.writeRetDetail(tmpRetDetail);
                                            }
                                        }
                                    }
                                } else {
                                    WriteBankLogLn("批量支付结果文件：" + fileName + "下载失败：" + error + "\r\n");
                                }
                            }
                        } else {
                            WriteBankLogLn("批量支付成功文件：" + fileName + "下载失败：" + tmpStrRetDownLoad[1] + "\r\n");
                        }
                    }
                }
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.toString();
            WriteBankLogLn("批量代发异常：" + e);
            e.printStackTrace();
        } finally {
            conn.close();
        }
        retAts.writeAfterDetail();
        return retAts;
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return null;
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return null;
    }

    //生成批量支付/代扣文件内容
    private String getPayFileContent(ReqBatPayRec p_req1988) throws Exception {
        String insertSQL = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,TRANSDATE,REQBATCHNO,REQSEQID,BANKREQSEQID) values (?,?,?,?,?,?);";
        Connection conn = FGBiz.getLocalDbConn();
        StringBuilder sb = new StringBuilder();
        try {
            sb.append("JIAMBZ:0").append(fileEndSp);//加密标志
            sb.append("DANWBH:00000000").append(fileEndSp);//单位编号 	目前为：00000000
            if ("198801".equals(p_req1988.reqHeader.commandCode)) {
                sb.append("YWZLBH:0008").append(fileEndSp);//0008：代发工资 	0092：其他代发  0169：本行批量代扣
            } else if ("9188".equals(p_req1988.reqHeader.transType)) {
                sb.append("YWZLBH:0169").append(fileEndSp);//0008：代发工资 	0092：其他代发  0169：本行批量代扣
            } else {
                sb.append("YWZLBH:0092").append(fileEndSp);//0008：代发工资 	0092：其他代发  0169：本行批量代扣
            }
            sb.append("KHZHLX:0").append(fileEndSp);//客户账号类型
            sb.append("KEHUZH:").append(p_req1988.ownAct).append(fileEndSp);//客户账号
            sb.append("HUOBDH:").append(convertCurToATS(p_req1988.ownCur)).append(fileEndSp);//货币代号
            sb.append("CHUIBZ:0").append(fileEndSp);//钞汇标志 	0：钞 	1：汇
            sb.append("ZHHUXZ:0001").append(fileEndSp);//账户性质 	一般是'0001'
            if ("1988".equals(p_req1988.reqHeader.transType)) {
                sb.append("SHOFBZ:1").append(fileEndSp);//代发代扣标志	1：代发 	2：代扣
            } else if ("9188".equals(p_req1988.reqHeader.transType)) {
                sb.append("SHOFBZ:2").append(fileEndSp);//代发代扣标志	1：代发 	2：代扣
            }
            sb.append("ZONGJE:").append(p_req1988.totalAmt).append(fileEndSp);//总金额
            sb.append("BISHUU:").append(p_req1988.totalNum).append(fileEndSp);//总笔数
            sb.append("RUZHRQ:").append(Format.Date8Format.format(Format.Date10Format.parse(p_req1988.payDate)));
            sb.append("-----------------------").append(fileEndSp);//入账日期 如:20050501
            int count = 0;
            while (p_req1988.readRecord()) {
                //记录批次号对应的银行支付批次号，供查询状态接口使用
                count++;
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, insertSQL, new Object[]{uuid, p_req1988.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1988.reqBatchNO, p_req1988.readedDetail.askNumber, count + ""});
                sb.append(p_req1988.readedDetail.recAct).append(fileSp);//收款账号
                sb.append(p_req1988.readedDetail.payAmount).append(fileSp);//金额
                sb.append(p_req1988.readedDetail.recName).append(fileSp);//姓名
                sb.append(p_req1988.readedDetail.memo).append(fileSp);//摘要
                sb.append(p_req1988.readedDetail.certNum).append(fileSp).append(fileEndSp);//证件号码
            }
        } catch (Exception e) {
            WriteBankLogLn(e.getMessage());
        } finally {
            conn.close();
        }
        return sb.toString();
    }
}
